﻿Imports System.Security.Cryptography
Imports System.Text

Imports DAL.DAL


Namespace BL


    Public Class Helper_BL

#Region "Encriptación"

        Public Shared Function encriptarAES(ByVal pTexto As String) As String
            Try
                'proveedor AES.
                Dim aes As New AesCryptoServiceProvider()
                Dim dest As Byte()
                aes.BlockSize = 128
                aes.KeySize = 128
                aes.IV = Encoding.UTF8.GetBytes("1234567812345678")
                aes.Key = Encoding.UTF8.GetBytes("1234567812345678")
                aes.Mode = CipherMode.CBC
                aes.Padding = PaddingMode.PKCS7
                'convertimos el string en un array de buyes.
                Dim src As Byte() = Encoding.Unicode.GetBytes(pTexto)
                'encriptar.
                Using enc As ICryptoTransform = aes.CreateEncryptor()
                    dest = enc.TransformFinalBlock(src, 0, src.Length)
                End Using
                'convertimos el array de bytes en uno de string Base64.
                Return Convert.ToBase64String(dest)

            Catch ex As Exception
                Throw ex
            End Try
        End Function

        Public Shared Function desencriptarAES(ByVal pTexto As String) As String
            Try
                'proveedor AES.
                Dim aes As New AesCryptoServiceProvider()
                aes.BlockSize = 128
                aes.KeySize = 128
                aes.IV = Encoding.UTF8.GetBytes("1234567812345678")
                aes.Key = Encoding.UTF8.GetBytes("1234567812345678")
                aes.Mode = CipherMode.CBC
                aes.Padding = PaddingMode.PKCS7
                'convertir un string Base64 a un array de bytes.
                Dim src As Byte() = System.Convert.FromBase64String(pTexto)
                'desencriptar.
                Using dec As ICryptoTransform = aes.CreateDecryptor()
                    Dim dest As Byte() = dec.TransformFinalBlock(src, 0, src.Length)
                    Return Encoding.Unicode.GetString(dest)
                End Using
            Catch ex As Exception
                Throw ex
            End Try
        End Function


        Public Shared Function encriptarMD5(ByVal pTexto As String) As String
            Dim passMD5 As String = ""
            Dim MD5 As New MD5CryptoServiceProvider
            Dim bytValue() As Byte
            Dim bytHash() As Byte
            Dim i As Integer

            bytValue = System.Text.Encoding.UTF8.GetBytes(pTexto)
            bytHash = MD5.ComputeHash(bytValue)
            MD5.Clear()

            For i = 0 To bytHash.Length - 1
                passMD5 &= bytHash(i).ToString("x").PadLeft(2, "0")
            Next

            Return passMD5
        End Function

#End Region


#Region "DVs"

        Shared Function calcularDVH(ByVal pTexto As String) As Integer
            Dim i As Integer = 0
            Dim DVH As Integer = 0
            'sin espacios iniciales ni finales
            pTexto = pTexto.Trim
            If (pTexto.Length > 0) Then
                'recorremos toda la cadena.
                For i = 0 To pTexto.Length - 1
                    'ascii x la posición del character.
                    DVH += (Asc(pTexto.Chars(i)) * i)
                Next
            End If
            Return DVH
        End Function


        Shared Sub setearDVH(ByVal ptabla As String, ByVal pid1 As Integer, ByVal pid2 As Integer, ByVal pdvh As Integer)
            DAL_ChequeoRecalculoDV.setearDVH(ptabla, pid1, pid2, pdvh)
        End Sub


        Shared Function calcularDVV(ptabla) As Integer
            Return Helper_DAL.CalcularDVV(ptabla)
        End Function


        Shared Sub setearDVV(ByVal ptabla As String, ByVal pdvv As Integer)
            Helper_DAL.setearDVV(ptabla, pdvv)
        End Sub


        Shared Function obtenerDVV(ByVal ptabla As String)
            Return Helper_DAL.obtenerDVV(ptabla)
        End Function


        Shared Function chequearDV(ByVal plogin As Boolean) As Boolean

            '**************** DVVs *******************
            Dim fallo As Boolean = False
            Dim DVVc As Integer = 0
            Dim DVVp As Integer = 0


            '//// **** BITACORA **** ////
            Try
                DVVc = CalcularDVV("bitacora")
                DVVp = obtenerDVV("bitacora")
            Catch ex As Exception
                Throw ex
            End Try
            
            If DVVc <> DVVp Then
                'falla integridad de la tabla (se borraron o agregaron registros).
                fallo = True
                If plogin = False Then
                    'si no estamos en el ingreso al sistema, nos da ópciones. 
                    Select Case MsgBox("Fallo de integridad en DVV - tabla bitacora - Desea recalcularlo? ", MsgBoxStyle.YesNoCancel, "Verificación de DVV")
                        Case MsgBoxResult.Yes
                            'setea el nuevo valor del dvv.
                            setearDVV("bitacora", DVVc)
                        Case MsgBoxResult.No
                            'no recalcula este dv, pero continua verrificando los demás.
                        Case MsgBoxResult.Cancel
                            'no recalcula más dvs, sale del ciclo (caso de tener muchos dv con problemas - habilita al usr salir a recalcular todo.
                            Return False
                    End Select
                End If
            End If
            '//// **** FAMILIA_PATENTE **** ////
            Try
                DVVc = CalcularDVV("familia_patente")
                DVVp = obtenerDVV("familia_patente")
            Catch ex As Exception
                Throw ex
            End Try
            
            If DVVc <> DVVp Then
                'falla integridad de la tabla (se borraron o agregaron registros).
                fallo = True
                If plogin = False Then
                    'si no estamos en el ingreso al sistema, nos da ópciones. 
                    Select Case MsgBox("Fallo de integridad en DVV - tabla familia_patente - Desea recalcularlo? ", MsgBoxStyle.YesNoCancel, "Verificación de DVV")
                        Case MsgBoxResult.Yes
                            'setea el nuevo valor del dvv.
                            setearDVV("familia_patente", DVVc)
                        Case MsgBoxResult.No
                            'no recalcula este dv, pero continua verrificando los demás.
                        Case MsgBoxResult.Cancel
                            'no recalcula más dvs, sale del ciclo (caso de tener muchos dv con problemas - habilita al usr salir a recalcular todo.
                            Return False
                    End Select
                End If
            End If
            '//// **** USUARIO_PATENTE **** ////
            Try
                DVVc = CalcularDVV("usuario_patente")
                DVVp = obtenerDVV("usuario_patente")
            Catch ex As Exception
                Throw ex
            End Try
            
            If DVVc <> DVVp Then
                'falla integridad de la tabla (se borraron o agregaron registros).
                fallo = True
                If plogin = False Then
                    'si no estamos en el ingreso al sistema, nos da ópciones. 
                    Select Case MsgBox("Fallo de integridad en DVV - tabla usuario_patente - Desea recalcularlo? ", MsgBoxStyle.YesNoCancel, "Verificación de DVV")
                        Case MsgBoxResult.Yes
                            'setea el nuevo valor del dvv.
                            setearDVV("usuario_patente", DVVc)
                        Case MsgBoxResult.No
                            'no recalcula este dv, pero continua verrificando los demás.
                        Case MsgBoxResult.Cancel
                            'no recalcula más dvs, sale del ciclo (caso de tener muchos dv con problemas - habilita al usr salir a recalcular todo.
                            Return False
                    End Select
                End If
            End If


            '**************** DVHs *******************
            Dim Ds As New DataSet
            Dim Dt As New DataTable
            Dim cadenastr As String

            'recorremos cada tabla que necesitamos verificar integridad 
            'calculamos los dvh - verificamos integridad en los campos de los registros).
            'calculamos los dvv - verificamos la integridad de la tabla (si nos add o del registros).

            '//// **** BITACORA **** ////. 

            'traemos en un DataTable contenido en un Dataset los registros de la tabla.
            Try
                Ds = DAL_ChequeoRecalculoDV.traerTabla("bitacora")
            Catch ex As Exception
                Throw ex
            End Try


            'por cada fila calculo los dvh y luego lo comparo con el que está persistido (última columna).
            'obs:calculamos el dvh sobre el campo encriptado - menos consumo cpu.

            For Each drow As DataRow In Ds.Tables(0).Rows
                cadenastr = ""
                Dim DVH As Integer = 0
                'id_usuario.
                cadenastr += drow.Item(1).ToString
                'fecha.
                cadenastr += drow.Item(2).ToString
                'descripcion.
                cadenastr += drow.Item(3).ToString
                'criticidad.
                cadenastr += drow.Item(4).ToString
                DVH = Helper_BL.CalcularDVH(cadenastr)

                'comparamos con el persistido.
                If DVH <> CInt(drow.Item(6)) Then
                    fallo = True
                    'el registro no verifica el dvh.
                    If plogin = False Then
                        'si no estamos en el ingreso al sistema, nos da ópciones. 
                        Select Case MsgBox("Fallo de integridad en DVH - tabla bitacora - registro= " & drow.Item(0).ToString & " - Desea recalcularlo? ", MsgBoxStyle.YesNoCancel, "Verificación de DVH")
                            Case MsgBoxResult.Yes
                                'setea el nuevo valor del dvh.
                                setearDVH("bitacora", CInt(drow.Item(0)), 0, DVH)
                            Case MsgBoxResult.No
                                'no recalcula este dv, pero continua verrificando los demás.
                            Case MsgBoxResult.Cancel
                                'no recalcula más dvs, sale del ciclo (caso de tener muchos dv con problemas - habilita al usr salir a recalcular todo.
                                Return False
                        End Select
                    End If
                End If
            Next



            '//// **** FAMILIA_PATENTE **** ////

            'traemos en un DataTable contenido en un Dataset los registros de la tabla.
            Try
                Ds = DAL_ChequeoRecalculoDV.traerTabla("familia_patente")
            Catch ex As Exception
                Throw ex
            End Try


            'por cada fila calculo los dvh y luego lo comparo con el que está persistido (última columna).
            'obs:calculamos el dvh sobre el campo encriptado - menos consumo cpu.

            For Each drow As DataRow In Ds.Tables(0).Rows
                cadenastr = ""
                Dim DVH As Integer = 0
                'id_familia.
                cadenastr += drow.Item(0).ToString
                'id_patente.
                cadenastr += drow.Item(1).ToString
                Try
                    DVH = Helper_BL.CalcularDVH(cadenastr)
                Catch ex As Exception
                    Throw ex
                End Try


                'comparamos con el persistido.
                If DVH <> CInt(drow.Item(2)) Then
                    fallo = True
                    'el registro no verifica el dvh.
                    If plogin = False Then
                        Select Case MsgBox("Fallo de integridad en DVH - tabla familia_patente - registro con id_familia=" & drow.Item(0).ToString & " y id_patente=" & drow.Item(1).ToString & " - Desea recalcularlo? ", MsgBoxStyle.YesNoCancel, "Verificación de DVH")
                            Case MsgBoxResult.Yes
                                'setea el nuevo valor del dvh.
                                setearDVH("familia_patente", CInt(drow.Item(0)), CInt(drow.Item(1)), DVH)
                            Case MsgBoxResult.No
                                'no recalcula este dv, pero continua verrificando los demás.
                            Case MsgBoxResult.Cancel
                                'no recalcula más dvs, sale del ciclo (caso de tener muchos dv con problemas - habilita al usr salir a recalcular todo.
                                Return False
                        End Select
                    End If
                End If
            Next


            '//// **** USUARIO_PATENTE **** ////

            'traemos en un DataTable contenido en un Dataset los registros de la tabla.
            Try
                Ds = DAL_ChequeoRecalculoDV.traerTabla("usuario_patente")
            Catch ex As Exception
                Throw ex
            End Try


            'por cada fila calculo los dvh y luego lo comparo con el que está persistido (última columna).
            'obs:calculamos el dvh sobre el campo encriptado - menos consumo cpu.

            For Each drow As DataRow In Ds.Tables(0).Rows
                cadenastr = ""
                Dim DVH As Integer = 0
                'id_usuario.
                cadenastr += drow.Item(0).ToString
                'id_patente.
                cadenastr += drow.Item(1).ToString
                'tipo.
                cadenastr += drow.Item(2).ToString
                Try
                    DVH = Helper_BL.CalcularDVH(cadenastr)
                Catch ex As Exception
                    Throw ex
                End Try


                'comparamos con el persistido.
                If DVH <> CInt(drow.Item(3)) Then
                    fallo = True
                    'el registro no verifica el dvh.
                    If plogin = False Then
                        Select Case MsgBox("Fallo de integridad en DVH - tabla usuario_patente - registro con id_usuario=" & drow.Item(0).ToString & " y id_patente=" & drow.Item(1).ToString & " - Desea recalcularlo? ", MsgBoxStyle.YesNoCancel, "Verificación de DVH")
                            Case MsgBoxResult.Yes
                                'setea el nuevo valor del dvh.
                                setearDVH("usuario_patente", CInt(drow.Item(0)), CInt(drow.Item(1)), DVH)
                            Case MsgBoxResult.No
                                'no recalcula este dv, pero continua verrificando los demás.
                            Case MsgBoxResult.Cancel
                                'no recalcula más dvs, sale del ciclo (caso de tener muchos dv con problemas - habilita al usr salir a recalcular todo.
                                Return False
                        End Select
                    End If
                End If
            Next



            'si verificó todo ok, mensaje.
            If fallo = False Then
                'integridad ok.
                Return True
            Else
                'integridad falló.
                Return False
            End If

        End Function


        Shared Sub recalcularTodosLosDV()

            '**************** DVHs *******************

            Dim Ds As DataSet
            Dim cadenastr As String
            Dim flagBitacoraDVH As Boolean = False
            Dim flagFamiliaPatenteDVH As Boolean = False
            Dim flagUsuarioPatenteDVH As Boolean = False
            Dim flagBitacoraDVV As Boolean = False
            Dim flagFamiliaPatenteDVV As Boolean = False
            Dim flagUsuarioPatenteDVV As Boolean = False


            '**** BITACORA ****.

            'traemos en un DataTable contenido en un Dataset los registros de la tabla.
            Try
                Ds = DAL_ChequeoRecalculoDV.traerTabla("bitacora")
            Catch ex As Exception
                Throw ex
            End Try

            'por cada fila calculo los dvh y luego lo persistimos.
            'obs:calculamos el dvh sobre el campo encriptado - menos consumo cpu.
            For Each drow As DataRow In Ds.Tables(0).Rows
                cadenastr = ""
                Dim DVH As Integer = 0
                'id_usuario.
                cadenastr += drow.Item(1).ToString
                'fecha.
                cadenastr += drow.Item(2).ToString
                'descripcion.
                cadenastr += drow.Item(3).ToString
                'criticidad.
                cadenastr += drow.Item(4).ToString
                Try
                    DVH = Helper_BL.CalcularDVH(cadenastr)
                    setearDVH("bitacora", CInt(drow.Item(0)), 0, DVH)
                Catch ex As Exception
                    Throw ex
                End Try

            Next
            flagBitacoraDVH = True



            '**** FAMILIA_PATENTE ****.

            'traemos en un DataTable contenido en un Dataset los registros de la tabla.
            Try
                Ds = DAL_ChequeoRecalculoDV.traerTabla("familia_patente")
            Catch ex As Exception
                Throw ex
            End Try

            'por cada fila calculo los dvh y luego lo persistimos.
            For Each drow As DataRow In Ds.Tables(0).Rows
                cadenastr = ""
                Dim DVH As Integer = 0
                'id_familia.
                cadenastr += drow.Item(0).ToString
                'id_patente.
                cadenastr += drow.Item(1).ToString
                Try
                    DVH = Helper_BL.CalcularDVH(cadenastr)
                    setearDVH("familia_patente", CInt(drow.Item(0)), CInt(drow.Item(1)), DVH)
                Catch ex As Exception
                    Throw ex
                End Try
                
            Next
            flagFamiliaPatenteDVH = True



            '**** USUARIO_PATENTE ****.

            'traemos en un DataTable contenido en un Dataset los registros de la tabla.
            Try
                Ds = DAL_ChequeoRecalculoDV.traerTabla("usuario_patente")
            Catch ex As Exception
                Throw ex
            End Try

            'por cada fila calculo los dvh y luego lo persistimos.
            For Each drow As DataRow In Ds.Tables(0).Rows
                cadenastr = ""
                Dim DVH As Integer = 0
                'id_usuario.
                cadenastr += drow.Item(0).ToString
                'id_patente.
                cadenastr += drow.Item(1).ToString
                'tipo.
                cadenastr += drow.Item(2).ToString
                Try
                    DVH = Helper_BL.CalcularDVH(cadenastr)
                    setearDVH("usuario_patente", CInt(drow.Item(0)), CInt(drow.Item(1)), DVH)
                Catch ex As Exception
                    Throw ex
                End Try
                
            Next
            flagUsuarioPatenteDVH = True



            '**************** DVVs *******************

            Dim DVVc As Integer

            '//// **** BITACORA **** ////
            DVVc = 0
            DVVc = CalcularDVV("bitacora")
            setearDVV("bitacora", DVVc)
            flagBitacoraDVV = True

            '//// **** FAMILIA_PATENTE **** ////
            DVVc = 0
            DVVc = CalcularDVV("familia_patente")
            setearDVV("familia_patente", DVVc)
            flagFamiliaPatenteDVV = True

            '//// **** USUARIO_PATENTE **** ////
            DVVc = 0
            DVVc = CalcularDVV("usuario_patente")
            setearDVV("usuario_patente", DVVc)
            flagUsuarioPatenteDVV = True


            If flagBitacoraDVH = True And flagFamiliaPatenteDVH = True And flagUsuarioPatenteDVH = True And flagBitacoraDVV = True And flagFamiliaPatenteDVV = True And flagUsuarioPatenteDVV = True Then
                MsgBox("Se recalcularon los dígitos verificadores de las Tablas ..", MsgBoxStyle.Information, "")
            End If


        End Sub


#End Region


#Region "Random"

        Public Shared Function generarCadenaAleatoria(ByVal longcadena As Integer) As String
            'dimensionamos un array para almacenar tanto las letras mayúsculas como minúsculas (52 letras).
            Dim letras(51) As String
            'llenamos el array.
            Dim n As Integer = 0
            Dim item As Integer
            For item = 65 To 90
                letras(n) = Chr(item)
                letras(n + 1) = letras(n).ToLower
                n += 2
            Next

            Dim cadenaAleatoria As String = ""
            'iniciamos el generador de números aleatorios
            Dim rnd As New Random(DateTime.Now.Millisecond)
            For n = 0 To longcadena
                Dim numero As Integer = rnd.Next(0, 51)
                cadenaAleatoria &= letras(numero)
            Next
            Return cadenaAleatoria
        End Function

#End Region

    End Class


End Namespace